<!-- Crop Image -->
<template>
  <div id="cropimage" ref="cropimage" @dblclick="cropimagecrop">
    <div id="app" :style="cssFun" v-show="dom">
      <!-- 灰色蒙版 -->
      <div class="layer"></div>
      <!-- 白色剪切 -->
      <div class="mask" ref="mask" :style="maskFun">
        <!-- 红色圆点 -->
        <img class="memg" :src="mengbanimg" alt="" />
        <div class="youxia" ref="dot"></div>
        <div class="youshang" ref="youshang">
          <img :src="img.youshang" alt="" srcset="" />
        </div>
        <div class="zuoshang" ref="zuoshang">
          <img :src="img.zuoshang" alt="" srcset="" />
        </div>
        <div class="zuoxia" ref="zuoxia">
          <img :src="img.zuoxia" alt="" srcset="" />
        </div>
      </div>

      <div class="mengban">
        <div
          class="mengban_div"
          v-for="(v, i) in memngbanList"
          :key="i"
          :style="v.checked ? 'border: 2px solid #d4d4d4;' : 'border:none'"
          @click="mengbandivClick(i)"
        >
          <img :src="v.src" alt="" srcset="" />
        </div>
      </div>
    </div>

    <div class="cropimage_bottom">
      <div @click="cropimageclose" class="cropimage_bot">
        <img :src="img.guanbiwhite" alt="" />关闭
      </div>
      <div @click="cropimagecrop" class="cropimage_bot">
        <img :src="img.cutwhite" alt="" />裁剪
      </div>
    </div>
    <canvas id="clipImg"></canvas>
  </div>
</template>

<script>
let elementResizeDetectorMaker = require("element-resize-detector");
import mixin from "@/utils/mixin";

export default {
  mixins: [mixin],
  props: {
    cropimg: {
      type: String,
      required: true,
    },
  },
  components: {},
  data() {
    //这里存放数据
    return {
      srcimg: this.cropimg,
      width: 0,
      height: 0,
      ox: null,
      oy: null,
      top: null,
      left: null,
      maskLeft: null,
      maskTop: null,
      mx: null,
      my: null,
      mw: null,
      mh: null,
      ml: null,
      mt: null,
      backSize: null,
      dom: false,
      mengbanimg: null,
      mengban: 0,
      memngbanList: [
        {
          checked: true,
          src: require("@/assets/img/无蒙版.png"),
        },
        {
          checked: false,
          src: require("@/assets/img/圆蒙版.png"),
        },
        {
          checked: false,
          src: require("@/assets/img/心蒙版.png"),
        },
      ],
    };
  },
  //监听属性 类似于data概念
  computed: {
    cssFun: function () {
      let { width, height, srcimg, backSize } = this;
      return `width:${width * backSize}px;
              height:${height * backSize}px;
              backgroundImage:url(' ${srcimg} ');
              backgroundSize:${width * backSize}px ${height * backSize}px ;
              position:absolute;`;
    },

    maskFun: function () {
      let { width, height, srcimg, backSize } = this;
      return `width: ${(width / 4) * backSize}px;
              height: ${(width / 4) * backSize}px;
              position: absolute;
              top: 0;
              left: 0;
              backgroundImage:url('${srcimg}');
              backgroundSize:${width * backSize}px ${height * backSize}px ;
              cursor: move`;
    },
  },
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {
    mengbandivClick(i) {
      this.memngbanList.forEach((v) => {
        v.checked = false;
      });
      this.memngbanList[i].checked = true;
      this.mengban = i;
      if (i == 0) this.mengbanimg = null;
      else if (i == 1) this.mengbanimg = this.img.mengban;
      else if (i == 2) this.mengbanimg = this.img.xinmeng;
    },
    //关闭裁剪
    cropimageclose() {
      this.$emit("cropimage");
    },
    //确认裁剪
    cropimagecrop() {
      let that = this;
      let canvas = document.getElementById("clipImg");
      let context = canvas.getContext("2d");
      let img = new Image();
      img.onload = function () {
        let x = that.$refs.mask.style.left.replace("px", "") / that.backSize;
        let y = that.$refs.mask.style.top.replace("px", "") / that.backSize;
        let w = that.$refs.mask.style.width.replace("px", "") / that.backSize;
        let h = that.$refs.mask.style.height.replace("px", "") / that.backSize;
        //原图绘制在画布上
        canvas.width = w;
        canvas.height = h;
        if (that.mengban == 0) {
          context.drawImage(img, -x, -y);
          let baseStr = canvas.toDataURL("image/png");
          that.$emit("cropimage", baseStr);
        } else {
          let img1 = new Image();
          img1.onload = function () {
            context.drawImage(img1, 0, 0, w, h);
            context.globalCompositeOperation = "source-in";
            context.drawImage(img, -x, -y);
            let baseStr = canvas.toDataURL("image/png");
            that.$emit("cropimage", baseStr);
          };
          img1.crossOrigin = "Anonymous";
          let imgsrc;
          if (that.mengban == 1) imgsrc = that.img.yuan;
          else if (that.mengban == 2) imgsrc = that.img.xinban;
          img1.src = imgsrc;
        }
      };
      img.crossOrigin = "Anonymous";
      img.src = this.srcimg;
    },
    //白色剪切----------------------------------------------------------
    mouseEventMask() {
      let that = this;
      this.$refs.mask.addEventListener("mousedown", function (e) {
        that.maskMousedown(e);
      });
      this.$refs.mask.addEventListener("mouseup", function () {
        that.maskMouseup();
      });
      this.$refs.mask.addEventListener("mouseout", function () {
        that.maskMouseup();
      });
    },
    // 鼠标落下
    maskMousedown(e) {
      //鼠标点击时位置
      this.mx = e.clientX;
      this.my = e.clientY;
      //mask宽高
      this.mw = parseInt(this.getStyle(this.$refs.mask, "width"));
      this.mh = parseInt(this.getStyle(this.$refs.mask, "height"));
      //mask原先偏移量
      this.ml = this.$refs.mask.offsetLeft;
      this.mt = this.$refs.mask.offsetTop;
      this.$refs.mask.addEventListener("mousemove", this.maskMousemove);
    },
    // 鼠标移动
    maskMousemove(e) {
      //鼠标移动时位置
      var dx = e.clientX;
      var dy = e.clientY;
      //移动距离
      var x = dx - this.mx + this.ml;
      //边界处理
      var y = dy - this.my + this.mt;
      if (x < 0) x = 0;
      else if (x + this.mw > this.width * this.backSize)
        x = this.width * this.backSize - this.mw;
      if (y < 0) y = 0;
      else if (y + this.mh > this.height * this.backSize)
        y = this.height * this.backSize - this.mh;
      this.$refs.mask.style.backgroundPositionX = -x + "px";
      this.$refs.mask.style.backgroundPositionY = -y + "px";
      this.$refs.mask.style.left = x + "px";
      this.$refs.mask.style.top = y + "px";
    },
    //鼠标抬起
    maskMouseup() {
      this.$refs.mask.removeEventListener("mousemove", this.maskMousemove);
    },

    //红色小点-----------------------------------------------
    mouseEventDot() {
      let that = this;
      //右下
      this.$refs.dot.addEventListener("mousedown", function (e) {
        that.dotMousedown(e);
      });
      this.$refs.dot.addEventListener("mouseup", function () {
        that.dotMouseup();
      });
      // //右上
      //  this.$refs.youshang.addEventListener("mousedown", function (e) {
      //   that.dotMousedown(e);
      // });
      // this.$refs.dot.addEventListener("mouseup", function () {
      //   that.dotMouseup();
      // });
    },
    //鼠标抬起
    dotMouseup() {
      document.removeEventListener("mousemove", this.youshangMousemove);
      document.removeEventListener("mousemove", this.dotMousemove);
    },
    //鼠标点击时位置
    //右上
    // youshangMousedown(e){
    //    e.stopPropagation();
    //   //鼠标点击时位置
    //   this.ox = e.clientX;
    //   this.oy = e.clientY;
    //   //mask宽高
    //   this.left = parseInt(this.getStyle(this.$refs.mask, "width"));
    //   this.top = parseInt(this.getStyle(this.$refs.mask, "height"));
    //   //mask原先偏移量
    //   this.maskLeft = this.$refs.mask.offsetLeft;
    //   this.maskTop = this.$refs.mask.offsetTop;
    //   document.addEventListener("mousemove", this.dotMousemove);
    // },
    //右下
    dotMousedown(e) {
      //停止冒泡
      e.stopPropagation();
      //鼠标点击时位置
      this.ox = e.clientX;
      this.oy = e.clientY;
      //mask宽高
      this.left = parseInt(this.getStyle(this.$refs.mask, "width"));
      this.top = parseInt(this.getStyle(this.$refs.mask, "height"));
      //mask原先偏移量
      this.maskLeft = this.$refs.mask.offsetLeft;
      this.maskTop = this.$refs.mask.offsetTop;
      document.addEventListener("mousemove", this.dotMousemove);
    },
    //鼠标移动
    dotMousemove(e) {
      //鼠标移动时位置
      var dx = e.clientX;
      var dy = e.clientY;
      //新坐标
      var x = dx - this.ox + this.left;
      var y = dy - this.oy + this.top;
      //边界处理
      if (x < 0) x = 0;
      else if (x + this.maskLeft > this.width * this.backSize)
        x = this.width * this.backSize - this.maskLeft;
      if (y < 0) y = 0;
      else if (y + this.maskTop > this.height * this.backSize)
        y = this.height * this.backSize - this.maskTop;
      this.$refs.mask.style.width = x + "px";
      this.$refs.mask.style.height = y + "px";
    },

    //获取图片宽高
    dealImage() {
      let that = this;
      let img = new Image();
      img.onload = function () {
        that.dom = true;
        let { width, height } = img;
        that.width = width;
        that.height = height;
        that.listeningDom();
      };
      img.crossOrigin = "Anonymous";
      img.src = that.srcimg;
    },
    //方法
    getStyle(element, styleName) {
      if (window.getComputedStyle) return getComputedStyle(element)[styleName];
      else {
        var style = element.currentStyle;
        if (style) {
          styleName = styleName.replace(/-([a-z])?/g, function (match, $1) {
            return $1.toUpperCase();
          });
          return style[styleName];
        }
      }
    },
    //监听dom
    listeningDom() {
      let erd = elementResizeDetectorMaker();
      erd.listenTo(this.$refs.cropimage, (ele) => {
        let maxW = ele.offsetWidth - 40;
        let maxH = ele.offsetHeight - 140;
        this.Screensize(maxW, maxH);
      });
    },
    Screensize(maxW, maxH) {
      let { width, height } = this;
      let backSize;
      //都大于宽高
      if (maxW < width && maxW < height) {
        if (width > height) backSize = maxW / width;
        else backSize = maxH / height;
        //其中一个大于最大边
      } else if (maxW < width || maxH < height) {
        if (width > maxW) backSize = maxW / width;
        else if (height > maxH) backSize = maxH / height;
        //都不大于最大边
      } else backSize = 1;
      this.backSize = backSize;
    },
  },
  beforeCreate() {}, //生命周期 - 创建之前
  //生命周期 - 创建完成（可以访问当前this实例）
  created() {},
  beforeMount() {}, //生命周期 - 挂载之前
  //生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {
    this.dealImage();
    this.mouseEventMask();
    this.mouseEventDot();
  },
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {
    document.removeEventListener("resize", this.listeningDom);
  }, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能，这个函数会触发
};
</script>
<style lang="less" scoped>
@import "../../assets/styles/frame.less";
#cropimage {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  // background: rgba(163, 120, 120, 0.24);
  z-index: 101;
  .divDAJ();
  overflow: hidden;
  .layer {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: #191b1cc1;
  }
  .youxia {
    width: 10px;
    height: 10px;
    position: absolute;
    right: -5px;
    bottom: -5px;
    border-radius: 50%;
    background-color: red;
    cursor: se-resize;
  }
  .zuoxia {
    position: absolute;
    bottom: -3px;
    left: -3px;
  }
  .zuoshang {
    position: absolute;
    top: -3px;
    left: -3px;
  }
  .youshang {
    position: absolute;
    top: -3px;
    right: -3px;
  }
  .cropimage_bottom {
    position: absolute;
    bottom: 20px;
    width: 270px;
    height: 40px;
    color: white;
    font-size: 14px;
    .divAJS();
    .cropimage_bot {
      width: 110px;
      height: 100%;
      background: #9e9d9d;
      border-radius: 20px;
      padding: 0 28px;
      box-shadow: 0px 10px 4px #14141452;

      .divAJS();
    }
  }
}
#clipImg,
#clip,
#cut {
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
}
.memg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.mengban {
  position: absolute;
  top: 34%;
  right: -120px;
  .mengban_div {
    width: 62px;
    height: 62px;
    padding: 2px;
    border-radius: 5px;
    margin: 2px 0;
    img {
      width: 100%;
      height: 100%;
    }
  }
}
</style>